package ro.gateway.aida.srv;

import java.io.IOException;
import java.util.Hashtable;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import ro.gateway.aida.servlet.Constants;
import ro.gateway.aida.utils.HttpUtils;



/**
 * <p>Title: Romanian AIDA</p>
 * <p>Description: :D application</p>
 * <p>Copyright: Copyright (comparator) 2003</p>
 * <p>Company: Romania Development Gateway </p>
 * @author Mihai Popoaei, mihai_popoaei@yahoo.com, smike@intellisource.ro
 * @version 1.0-* @version $Id: EditorServlet.java,v 1.1 2004/10/24 23:37:04 mihaipostelnicu Exp $
 */
public abstract class EditorServlet extends HttpServlet
{
      /**
       * numele atributului cu cheia de editare
       * (request para, request attr, bean attr_name)
       */
      public static final String PNAME_KEY = "key";

      /**
       * numele attributului din sesiune (hashtable)
       * in care stau beanurile
       */
      public static final String PNAME_BEAN = "bean"; // request attr: bean

      /**
       * numele atributului in care e stocat refererul
       */
      public static final String PNAME_REFERER = "referer";

      /**
       * screenurile din jsp
       */
      public static final String PNAME_SCREEN = "screen";
      public static final String PV_SCR_CONFIRM = "scr_confirm";
      public static final String PV_SCR_EDIT = "scr_edit";
      public static final String PV_SCR_ERROR = "scr_error";

      /**
       * actiunea
       */
      public static final String PNAME_ACTION = "action";
      public static final String PV_ACTION_EDIT = "edit";
      public static final String PV_ACTION_DELETE = "del";
      public static final String PV_ACTION_CANCEL = "cancel";
      public static final String PV_ACTION_SAVE = "save";
      public static final String PV_ACTION_CONFIRM = "confirm";
      public static final String PV_ACTION_NEW = "new";

      /**
       * @param request
       * @param response
       * @throws ServletException
       * @throws IOException
       */
      public final void doPost(
            HttpServletRequest request,
            HttpServletResponse response )
            throws ServletException, IOException
      {

            response.setHeader( "Expires", "0" );
            response.setHeader( "Pragma", "no-cache" );

            String key = HttpUtils.getValidTrimedString( request, "key", null );
            ServletContext application = this.getServletContext();

            if ( key == null )
            {
                  //  nouaeditare

                  start_editing( application, request, response );

                  String action =
                        ( String ) ( ( Hashtable ) request.getAttribute( PNAME_BEAN ) ).get(
                              PNAME_ACTION );

                  if ( PV_ACTION_DELETE.equals( action ) )
                  {
                        request.setAttribute( PNAME_SCREEN, PV_SCR_CONFIRM );
                  }
                  else
                  {
                        request.setAttribute( PNAME_SCREEN, PV_SCR_EDIT );
                  }

                  if ( !response.isCommitted() )
                  {
                        request.getRequestDispatcher( getJSP_PAGE() ).forward(
                              request,
                              response );
                  }

                  return;
            }

            // pun in request keya si beanul
            request.setAttribute( PNAME_KEY, key );

            Hashtable beans =
                  ( Hashtable ) request.getSession().getAttribute( getPNAME_BEANS() );

            if ( beans == null )
            {
                  response.sendError(
                        HttpServletResponse.SC_EXPECTATION_FAILED,
                        "beans not in session ! " );

                  return;
            }

            request.setAttribute( PNAME_BEAN, beans.get( key ) );

            String action =
                  HttpUtils.getValidTrimedString(
                        request,
                        PNAME_ACTION,
                        PV_ACTION_CANCEL );
//            System.err.println( "action:" + action );
            Hashtable bean = ( Hashtable ) request.getAttribute( PNAME_BEAN );

            if ( PV_ACTION_CANCEL.equals( action ) )
            {
                  cancel( request, response );
            }
            else if ( PV_ACTION_EDIT.equals( action ) )
            {
                  edit( request, response );
            }
            else if ( PV_ACTION_SAVE.equals( action ) )
            {
                  save( application, request, response );
            }
            else if ( PV_ACTION_CONFIRM.equals( action ) )
            {
                  confirm( request, response );
            }
            else if ( PV_ACTION_DELETE.equals( action ) )
            {
                  bean.put( PNAME_ACTION, action );
                  confirm( request, response );

            }
            else
            {
                  other_action_performed( request, response, action );
            }

            return;
      }

      /**
       * @param request the Http Request
       * @return the bean storing info for that request
       */
      public static Hashtable getBean( HttpServletRequest request )
      {
            Hashtable r = ( Hashtable ) request.getAttribute( PNAME_BEAN );

            if ( r == null )
            {
                  r = new Hashtable();
                  request.setAttribute( PNAME_BEAN, r );
            }

            return r;
      }


      protected abstract void other_action_performed(
            HttpServletRequest request,
            HttpServletResponse response,
            String action )
            throws IOException, ServletException;

      /**
       * @param request
       * @param response
       */
      protected abstract void confirm(
            HttpServletRequest request,
            HttpServletResponse response )
            throws IOException, ServletException;

      /**
       * @param request
       * @param response
       * @throws IOException
       * @throws ServletException
       */
      protected abstract void save(
            ServletContext application,
            HttpServletRequest request,
            HttpServletResponse response )
            throws IOException, ServletException;

      /**
       * apelata la edit
       * @param request
       * @param response
       * @throws IOException
       * @throws ServletException
       */
      protected abstract void edit(
            HttpServletRequest request,
            HttpServletResponse response )
            throws IOException, ServletException;

      /**
       * apelata cand se da cancel la forma
       *
       * @param request
       * @param response
       * @throws IOException
       * @throws ServletException
       */
      protected void cancel(
            HttpServletRequest request,
            HttpServletResponse response )
            throws IOException, ServletException
      {

            String key = ( String ) request.getAttribute( PNAME_KEY );

            Hashtable beans =
                  ( Hashtable ) request.getSession().getAttribute( getPNAME_BEANS() );
            Hashtable bean = ( Hashtable ) request.getAttribute( PNAME_BEAN );

            if ( ( key == null ) || ( bean == null ) )
            {
                  response.sendError(
                        HttpServletResponse.SC_EXPECTATION_FAILED,
                        "bad[::] request" );

                  return;
            }

            String referer = ( String ) bean.get( PNAME_REFERER );
//            System.err.println( "redirect to:" + referer );
            response.sendRedirect( referer );

            beans.remove( key );
      }

      /**
       *
       * @param request
       * @param response
       * @throws IOException
       * @throws ServletException
       */
      protected void start_editing(
            ServletContext application,
            HttpServletRequest request,
            HttpServletResponse response )
            throws IOException, ServletException
      {

            HttpSession session = request.getSession();

            // creez o noua cheie
            String key;
            key = HttpUtils.getHash( session.getId() + System.currentTimeMillis() );
            request.setAttribute( PNAME_KEY, key );

            // este hashtableul cu beanurile in sessiune ? daca nu il creez
            Hashtable beans = ( Hashtable ) session.getAttribute( getPNAME_BEANS() );

            if ( beans == null )
            {
                  beans = new Hashtable();
                  session.setAttribute( getPNAME_BEANS(), beans );
            }

            // creez beanul nou
            Hashtable bean = new Hashtable();
            bean.put( PNAME_KEY, key );
            bean.put(
                  PNAME_REFERER,
                  HttpUtils.getReferer(
                        request,
                        PNAME_REFERER,
                        "/",
                        new String[]{getJSP_PAGE()} ) );
            request.setAttribute( PNAME_BEAN, bean );

            String action =
                  HttpUtils.getValidTrimedString(
                        request,
                        PNAME_ACTION,
                        PV_ACTION_NEW );
            bean.put( PNAME_ACTION, action );

            // pun beanul creat in hashtableul cu beanuri dupa cheia creata
            beans.put( key, bean );

      }

      /**
       *
       * @param request
       * @param response
       * @throws ServletException
       * @throws IOException
       */
      public final void doGet(
            HttpServletRequest request,
            HttpServletResponse response )
            throws ServletException, IOException
      {
            doPost( request, response );
      }

      /**
       *
       * @return
       */
      public abstract String getPNAME_BEANS();

      /**
       *
       * @return
       */
      public abstract String getJSP_PAGE();

      /**
       * returns the CFService object
       * @return CFService
       */
      protected ICFService getCFService()
      {
            ServletContext application = this.getServletContext();
            ICFService cfService =
                  ( ICFService )
                  ( ( Hashtable ) application.getAttribute( Constants.SERVICES ) ).get(
                        Constants.SERVICE_CF );
            return cfService;
      }

      /**
       * @param bean the Hashtable bean
       * @param s the key
       * @param o the content
       */
      public static void beanSync( Hashtable bean, String s, Object o )
      {
            if ( s == null )
                  return;
            if ( o == null )
            {
                  bean.remove( s );
                  return;
            }
            bean.put( s, o );
      }

      protected void reload(
            String screen,
            HttpServletRequest request,
            HttpServletResponse response )
      {

            request.setAttribute( PNAME_SCREEN, screen );
            try
            {
                  request.getRequestDispatcher( getJSP_PAGE() ).forward(
                        request,
                        response );
            }
            catch ( ServletException ex )
            {
                  ex.printStackTrace();
            }
            catch ( IOException ex )
            {
                  ex.printStackTrace();
            }
            catch ( Exception ex )
            {
                  ex.printStackTrace();
            }


      }
}
